package top.haijunit.work.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import top.haijunit.work.core.doamin.PageQuery;
import top.haijunit.work.core.doamin.ResultPage;

import java.util.Collection;
import java.util.List;

/**
 * 测试缓存功能
 *
 * @author zhanghaijun
 * @since 2024-09-05
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@CacheConfig(cacheNames = {"cache:test"})
public class CacheTestService {

    private final List<String> dataList = CollUtil.newArrayList("a", "b", "c");

    /**
     * 查询分页列表。
     * 当查询条件为空或参数长度为0时，缓存查询结果。
     */
    @Cacheable(key = "#pageQuery.getPage() + '_' + #pageQuery.getSize()", condition = "#info == null || #info.isEmpty()")
    public ResultPage<String> selectPageList(PageQuery pageQuery, String info) {
        log.info("分页查询，条件:{}, 分页: {}", info, pageQuery);
        Collection<String> list = selectList(info).stream().skip(pageQuery.offset()).limit(pageQuery.getSize()).toList();
        return ResultPage.of(list, pageQuery.getPage(), pageQuery.getSize(), list.size());
    }

    /**
     * 查询所有或根据参数过滤的数据列表。
     * 使用@Cacheable注解来缓存查询结果。
     */
    @Cacheable(key = "'list'", condition = "#dto ==null || #dto.length() == 0")
    public Collection<String> selectList(String dto) {
        log.info("查询列表，条件:{}", dto);
        if (CharSequenceUtil.isBlank(dto)) {
            return dataList;
        }
        return dataList.stream().filter(item -> CharSequenceUtil.containsAnyIgnoreCase(item, dto)).toList();
    }

    /**
     * 根据code获取详细信息。
     * 使用@Cacheable注解来缓存单个对象的详细信息。
     */
    @Cacheable(key = "#code", unless = "#result == null")
    public String selectDetail(String code) {
        log.info("查询详情，code:{}", code);
        if (CharSequenceUtil.isBlank(code)) {
            return null;
        }
        return dataList.stream().filter(item -> CharSequenceUtil.containsAnyIgnoreCase(item, code)).findFirst().orElse(null);
    }

    /**
     * 插入新数据。
     * 使用@CachePut注解来更新缓存中的值。
     */
    @CacheEvict(allEntries = true)
    public String insert(String code) {
        log.info("插入数据，code:{}", code);
        if (CharSequenceUtil.isBlank(code)) {
            return null;
        }
        if (dataList.contains(code)) {
            log.warn("插入失败，数据已存在: {}", code);
            return null;
        }
        dataList.add(code);
        return code;
    }

    /**
     * 删除数据。
     * 使用@CacheEvict注解来从缓存中移除项目。
     */
    @CacheEvict(allEntries = true)
    public String delete(String code) {
        log.info("删除数据，code:{}", code);
        if (CharSequenceUtil.isBlank(code)) {
            return null;
        }
        if (!dataList.contains(code)) {
            log.warn("删除失败，数据不存在: {}", code);
            return null;
        }
        dataList.remove(code);
        return code;
    }
}
